import { Algorithm } from "../types"

// 数据模型定义
interface MPLPNode {
  id: any
  type: string
  attributes: Record<string, any>
}

interface MPLPEdge {
  source: any
  target: any
  type?: string
  weight?: number
  attributes: Record<string, any>
}

interface MPLPGraph {
  nodes: MPLPNode[]
  edges: MPLPEdge[]
}

interface MPLPInputParams {
  nodes: MPLPNode[]
  edges: MPLPEdge[]
  meta_paths: string[][]
  source_type: string
  target_type: string
  top_k: number
}

interface MPLPPrediction {
  source: any
  target: any
  score: number
  meta_path?: string
}

interface MPLPOutputParams {
  predictions: MPLPPrediction[]
  algorithm: string
  parameters: Record<string, any>
  path_counts: Record<string, number>
  execution_time: number
}

interface AlgorithmRequest {
  task_id: string
  task_callback_url?: string
  input_params: {
    mplp_params: MPLPInputParams
  }
}

// 元路径链接预测算法实现
export const MetaPathLinkPrediction: Algorithm = {
  name: "元路径链接预测算法(MPLP)",
  description: "基于元路径的异构图链接预测算法，用于预测图中节点之间可能存在的链接",
  configOptions: [
    {
      id: "source_type",
      label: "源节点类型",
      type: "text",
      defaultValue: "用户",
      placeholder: "例如: 用户"
    },
    {
      id: "target_type",
      label: "目标节点类型",
      type: "text",
      defaultValue: "物品",
      placeholder: "例如: 物品"
    },
    {
      id: "meta_paths",
      label: "元路径定义",
      type: "textarea",
      defaultValue: '["用户", "物品", "用户"]\n["用户", "标签", "物品"]',
      placeholder: '请输入元路径，每行一个，格式如：["用户", "物品", "用户"]'
    },
    {
      id: "top_k",
      label: "返回结果数量",
      type: "number",
      defaultValue: 10,
      placeholder: "10"
    },
    {
      id: "inputData",
      label: "输入数据",
      type: "textarea",
      placeholder: `请输入JSON格式的图数据，例如：
{
  "nodes": [
    {
      "id": "u1",
      "type": "用户",
      "attributes": {"age": 25, "gender": "男"}
    },
    {
      "id": "i1",
      "type": "物品",
      "attributes": {"category": "电子产品"}
    }
  ],
  "edges": [
    {
      "source": "u1",
      "target": "i1",
      "type": "购买",
      "weight": 1.0,
      "attributes": {"timestamp": "2023-01-01"}
    }
  ]
}`
    }
  ],
  execute: async (config) => {
    try {
      // 生成唯一的任务ID
      const taskId = `mplp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
      
      // 解析输入数据
      let graphData: MPLPGraph
      try {
        graphData = JSON.parse(config.inputData)
      } catch (e) {
        throw new Error("输入数据必须是有效的JSON格式")
      }

      // 验证输入数据结构
      if (!graphData.nodes || !Array.isArray(graphData.nodes) || !graphData.edges || !Array.isArray(graphData.edges)) {
        throw new Error("输入数据必须包含nodes和edges数组")
      }

      // 解析元路径
      let metaPaths: string[][] = []
      try {
        metaPaths = config.meta_paths.split('\n')
          .filter((line: string) => line.trim())
          .map((line: string) => JSON.parse(line.trim()))
      } catch (e) {
        throw new Error("元路径格式错误，应为每行一个JSON数组")
      }

      // 准备请求数据
      const requestData: AlgorithmRequest = {
        task_id: taskId,
        task_callback_url: "",
        input_params: {
          mplp_params: {
            nodes: graphData.nodes,
            edges: graphData.edges,
            meta_paths: metaPaths,
            source_type: config.source_type || "用户",
            target_type: config.target_type || "物品",
            top_k: Number(config.top_k) || 10
          }
        }
      }

      // 创建任务
      const createResponse = await fetch("http://172.16.4.151:1122/api/mplp/create", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(requestData)
      })

      if (!createResponse.ok) {
        const errorData = await createResponse.json()
        if (createResponse.status === 422) {
          const validationErrors = errorData.detail || []
          const errorMessages = validationErrors.map((err: any) => 
            `${err.loc?.join('.')}: ${err.msg}`
          ).join('\n')
          throw new Error(`数据验证错误:\n${errorMessages}`)
        }
        throw new Error(errorData.detail || "创建任务失败")
      }

      // 执行任务
      const executeResponse = await fetch(`http://172.16.4.151:1122/api/mplp/execute/${taskId}`, {
        method: "POST"
      })

      if (!executeResponse.ok) {
        const errorData = await executeResponse.json()
        throw new Error(errorData.detail || "执行任务失败")
      }

      // 轮询获取结果
      let result
      let attempts = 0
      const maxAttempts = 60

      while (attempts < maxAttempts) {
        const getResultResponse = await fetch(`http://172.16.4.151:1122/api/mplp/result/${taskId}`)
        
        if (!getResultResponse.ok) {
          const errorData = await getResultResponse.json()
          throw new Error(errorData.detail || "获取结果失败")
        }

        result = await getResultResponse.json()
        
        // 添加日志以便调试
        console.log(`第${attempts + 1}次尝试获取结果:`, result.task_status)

        if (result.task_status === "COMPLETED") {
          break
        } else if (result.task_status === "FAILED") {
          throw new Error(result.error_message || "任务执行失败")
        }

        await new Promise(resolve => setTimeout(resolve, 1000))
        attempts++
      }

      if (attempts >= maxAttempts) {
        throw new Error("任务执行超时")
      }

      // 处理结果
      if (!result.output_params?.mplp_results) {
        throw new Error("结果结构不正确，缺少mplp_results")
      }

      const outputParams = result.output_params.mplp_results
      
      // 生成结果摘要
      const resultText = `链接预测完成：
预测链接数量: ${outputParams.predictions.length}
算法: ${outputParams.algorithm || "元路径链接预测"}
执行完成，耗时: ${outputParams.execution_time ? outputParams.execution_time.toFixed(2) : "0"}秒`

      // 生成预测结果表格
      const predictionsText = outputParams.predictions.length > 0 
        ? `预测的链接:
${outputParams.predictions.map((pred: MPLPPrediction, index: number) => 
  `${index+1}. ${pred.source} → ${pred.target} (置信度: ${(pred.score * 100).toFixed(2)}%)`
).join('\n')}`
        : "未找到预测链接"

      // 元路径统计
      const pathCountsText = Object.keys(outputParams.path_counts || {}).length > 0
        ? `元路径统计:
${Object.entries(outputParams.path_counts).map(([path, count]) => 
  `- ${path}: ${count}`
).join('\n')}`
        : "无元路径统计数据"

      return {
        result: `${resultText}\n\n${predictionsText}\n\n${pathCountsText}`,
        steps: [],
        executionTime: outputParams.execution_time || 0,
        details: {
          predictions: outputParams.predictions.map((pred: MPLPPrediction) => ({
            source: pred.source,
            target: pred.target,
            score: pred.score,
            meta_path: pred.meta_path
          })),
          pathCounts: outputParams.path_counts || {},
          parameters: outputParams.parameters || {}
        }
      }
    } catch (e: any) {
      console.error("MPLP算法执行出错:", e)
      throw e
    }
  }
} 